package cn.akira.domain.strategy.service.rule.tree.factory.engine.impl;

import cn.akira.domain.strategy.model.vo.RuleLogicCheckTypeVO;
import cn.akira.domain.strategy.model.vo.RuleTreeNodeLineVO;
import cn.akira.domain.strategy.model.vo.RuleTreeNodeVO;
import cn.akira.domain.strategy.model.vo.RuleTreeVO;
import cn.akira.domain.strategy.service.rule.tree.ILogicTreeNode;
import cn.akira.domain.strategy.service.rule.tree.factory.DefaultTreeFactory;
import cn.akira.domain.strategy.service.rule.tree.factory.engine.IDecisionTreeEngine;
import lombok.extern.slf4j.Slf4j;

import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author fjl95
 * @date 2025/5/16
 * @description 规则树组合引擎(之前的策略工程和责任链，一个直接装进map就可以，一个只需要做一下简单的链接，并不需要单独拿出一个拼接类)
 */
@Slf4j
public class DecisionTreeEngine implements IDecisionTreeEngine {

    private final Map<String, ILogicTreeNode> logicTreeNodeGroup;

    private final RuleTreeVO ruleTreeVO;

    public DecisionTreeEngine(Map<String, ILogicTreeNode> logicTreeNodeGroup, RuleTreeVO ruleTreeVO) {
        this.logicTreeNodeGroup = logicTreeNodeGroup;
        this.ruleTreeVO = ruleTreeVO;
    }

    @Override
    public DefaultTreeFactory.StrategyAwardVO process(String userId, Long strategyID, Integer awardId, Date endDateTime) {
        DefaultTreeFactory.StrategyAwardVO strategyAwardVO = null;

        //获取根节点名称
        String nextNode = ruleTreeVO.getTreeRootRuleNode();
        //获得所有的名称-节点实体对应map
        Map<String, RuleTreeNodeVO> treeNodeMap =  ruleTreeVO.getTreeNodeMap();
        //拿到根节点实体 剩余链接都在节点实体之间通过连线实体进行
        RuleTreeNodeVO ruleTreeNode = treeNodeMap.get(nextNode);

        while(null != nextNode) {
            //拿到当前树节点实体对应的校验类
            ILogicTreeNode logicTreeNode = logicTreeNodeGroup.get(ruleTreeNode.getRuleKey());
            //查询校验时需要的Value信息
            String ruleValue = ruleTreeNode.getRuleValue();
            //传入校验类执行校验
            DefaultTreeFactory.TreeActionEntity treeActionEntity = logicTreeNode.logic(userId, strategyID, awardId,ruleValue,endDateTime);
            //校验结果状态
            RuleLogicCheckTypeVO ruleLogicCheckTypeVO = treeActionEntity.getRuleLogicCheckType();
            //校验奖品结果
            strategyAwardVO = treeActionEntity.getStrategyAwardVO();
            log.info("决策树引擎【{}】treeId:{} node:{} code:{}", ruleTreeVO.getTreeName(), ruleTreeVO.getTreeId(), nextNode, ruleLogicCheckTypeVO.getCode());
            //根据校验结果和当前节点拥有的线找到下一个节点
            nextNode = nextNode(ruleLogicCheckTypeVO.getCode(),ruleTreeNode.getTreeNodeLineVOList());
            //拿到下一个节点实体
            ruleTreeNode = treeNodeMap.get(nextNode);
        }
        return strategyAwardVO;
    }

    private String nextNode(String matterValue, List<RuleTreeNodeLineVO> ruleTreeNodeLineVOList) {
        if (ruleTreeNodeLineVOList == null || ruleTreeNodeLineVOList.isEmpty()) {
            return null;
        }
        //遍历当前节点所有连线，查找是否有连线等于当前结果状态
        for (RuleTreeNodeLineVO nodeLine : ruleTreeNodeLineVOList) {
            if(decisionLogic(matterValue, nodeLine)) {
                return nodeLine.getRuleNodeTo();
            }
        }
        //执行到这，则说明已经没有连线，返回null
        return null;
    }
    public boolean decisionLogic(String matterValue, RuleTreeNodeLineVO nodeLine) {
        switch (nodeLine.getRuleLimitType()) {
            case EQUAL:
                return matterValue.equals(nodeLine.getRuleLimitValue().getCode());
            // 以下规则暂时不需要实现
            case GT:
            case LT:
            case GE:
            case LE:
            default:
                return false;
        }
    }

}
